import router from '@/router'
import Vue from 'vue'
import { Message } from 'element-ui';
import moment from "moment";
import * as cache from "@/common/cache";

/*
* 格式化金额
* number：要格式化的数字
* decimals：保留几位小数
* decPoint：小数点符号
* thousandsSep：千分位符号
* roundTag:舍入参数 "ceil"向上取,"floor"向下取,"round" 四舍五入
* */
export const formatAmount = (number, decimals = 2, decPoint = '.', thousandsSep = ',', roundTag = 'round') => {
    number = (number + '').replace(/[^0-9+-Ee.]/g, '')
    roundTag = roundTag || 'ceil' // "ceil","floor","round"
    var n = !isFinite(+number) ? 0 : +number
    var prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
    var s = ''
    var toFixedFix = function (n, prec) {
        var k = Math.pow(10, prec)
        // console.log()

        return '' + parseFloat(Math[roundTag](parseFloat((n * k).toFixed(prec * 2))).toFixed(prec * 2)) / k
    }
    s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
    var re = /(-?\d+)(\d{3})/
    while (re.test(s[0])) {
        s[0] = s[0].replace(re, '$1' + thousandsSep + '$2')
    }

    if ((s[1] || '').length < prec) {
        s[1] = s[1] || ''
        s[1] += new Array(prec - s[1].length + 1).join('0')
    }
    return s.join(decPoint)
}

// console.log(formatAmount(2.000, 3, '.', '.'))

/**
 * 跳转登录页
 * 携带当前页面路由，以期在登录页面完成登录后返回当前页面
 */
export const toLogin = (fullPath = true) => {
    // 清除当前站点所有会话数据
    window.sessionStorage.clear()
    if (fullPath) {
        // console.log(`toLogin... ====> fullPath: ${router.currentRoute.fullPath}, isLoginPath: ${router.currentRoute.fullPath.startsWith('/login')}`)
    }
    router.replace({
        path: '/',
        // query: {
        //   redirect: fullPath ? (router.currentRoute.fullPath.startsWith('/') ? '' : router.currentRoute.fullPath) : ''
        // }
    }).then(r => {
        // console.log(r)
    })
}

/**
 * 获取查询字符串
 * @param key
 * @returns {*}
 */
export const getQueryString = (key) => {
    // 获取URL中?之后的字符
    var str = location.search
    // console.log(str)
    str = str.substring(1, str.length)

    // 以&分隔字符串，获得类似name=xiaoli这样的元素数组
    var arr = str.split('&')
    // eslint-disable-next-line no-new-object
    var obj = new Object()

    // 将每一个数组元素以=分隔并赋给obj对象
    for (var i = 0; i < arr.length; i++) {
        // eslint-disable-next-line camelcase
        var tmp_arr = arr[i].split('=')
        obj[decodeURIComponent(tmp_arr[0])] = decodeURIComponent(tmp_arr[1])
    }
    return obj[key]
}

/**
 * 计算百分比
 * @param val       分子
 * @param total     分母
 * @param decimal   保留几位小数
 */
export const calcPercentage = (val, total, decimal = 1) => {
    if (!(val && total)) {
        return 0
    }
    if (total === 0 || val === 0) {
        return 0
    }
    return Number((val / total * 100).toFixed(decimal))
}

/**
 * 转换单位
 * @param val               值
 * @param startUnitIndex    起始单位的下标
 * @param step              单位进制，如每1000进行转换
 * @param unit              单位
 * @returns {*|string}
 */
export const convertUnit = (val, startUnitIndex = 0, step = 1000, unit = ['', 'k']) => {
    if (!val || val === '' || val === null || val === undefined) {
        return 0
    }
    // 对比值
    // const compareVal = Math.abs(val)
    // // 1e3为10的三次方 1e4为10的四次方以此类推
    // if (compareVal >= 0 && compareVal < 1e3 / 2) {
    //     return val
    // } else if (compareVal >= 1e3 / 2 && compareVal < 1e4) {
    //     return
    // }

    if (Math.abs(val) >= step) {
        return convertUnit(val / step, startUnitIndex + 1, step, unit)
    }
    return `${Number(val).toFixed(1) * 100 / 100}${unit[startUnitIndex]}`
}


/**
 * 图片格式化
 * @param prefix
 * @param val
 * @param defaultVal
 * @returns {string|*}
 */
export const imgFormat = (prefix, val, defaultVal) => {
    // console.log(`val: ${val}, defaultVal: ${defaultVal}`)
    if (val && val !== '') {
        if (val.startsWith('http')) {
            return val
        } else {
            return prefix + val
        }
    } else {
        return defaultVal || ''
    }
}

/**
 * 给对象赋值(仅赋值目标对象有的属性)
 * @param target
 * @param source
 * @param number2str 数字类型转字符串类型
 * @param zero2empty
 */
export const assignOnlyTarget = (target, source, number2str, zero2empty) => {
    if (target && source) {
        const targetKeys = Object.keys(target)
        const sourceKeys = Object.keys(source)
        targetKeys.forEach(t => {
            sourceKeys.forEach(s => {
                if (s === t) {
                    if (number2str) {
                        target[t] = (typeof source[s] === 'number' && !isNaN(source[s])) ? String(zero2empty ? (source[s] === 0 ? '' : source[s]) : source[s]) : source[s]
                    } else {
                        target[t] = source[s]
                    }
                }
            })
        })
    }
}

/**
 * 下载txt文件
 * @param filename
 * @param text
 */
export const downloadTxt = (filename, text) => {
    var pom = document.createElement('a')
    pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text))
    pom.setAttribute('download', filename)
    if (document.createEvent) {
        var event = document.createEvent('MouseEvents')
        event.initEvent('click', true, true)
        pom.dispatchEvent(event)
    } else {
        pom.click()
    }
}

/**
 * url转base64
 * 原理： 利用canvas.toDataURL的API转化成base64
 * @param url
 * @returns {Promise<unknown>}
 */
export const urlToBase64 = (url) => {
    return new Promise((resolve, reject) => {
        const image = new Image()
        image.onload = function () {
            const canvas = document.createElement('canvas')
            canvas.width = this.naturalWidth
            canvas.height = this.naturalHeight
            // 将图片插入画布并开始绘制
            canvas.getContext('2d').drawImage(image, 0, 0)
            // result
            const result = canvas.toDataURL('image/png')
            resolve(result)
        }
        // CORS 策略，会存在跨域问题https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror
        image.setAttribute('crossOrigin', 'Anonymous')
        image.src = url
        // 图片加载失败的错误处理
        image.onerror = () => {
            reject(new Error('图片流异常'))
        }
    })
}

/**
 * base64转blob
 * 原理：利用URL.createObjectURL为blob对象创建临时的URL
 * @param b64data
 * @param contentType
 * @param sliceSize
 * @returns {Promise<unknown>}
 */
export const base64ToBlob = ({
                                 b64data = '',
                                 contentType = '',
                                 sliceSize = 512
                             } = {}) => {
    return new Promise((resolve) => {
        // 使用 atob() 方法将数据解码
        const byteCharacters = atob(b64data)
        const byteArrays = []
        for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
            const slice = byteCharacters.slice(offset, offset + sliceSize)
            const byteNumbers = []
            for (let i = 0; i < slice.length; i++) {
                byteNumbers.push(slice.charCodeAt(i))
            }
            // 8 位无符号整数值的类型化数组。内容将初始化为 0。
            // 如果无法分配请求数目的字节，则将引发异常。
            byteArrays.push(new Uint8Array(byteNumbers))
        }
        let result = new Blob(byteArrays, {
            type: contentType
        })
        result = Object.assign(result, {
            // jartto: 这里一定要处理一下 URL.createObjectURL
            preview: URL.createObjectURL(result),
            name: 'example.png'
        })
        resolve(result)
    })
}

/**
 * blob转base64
 * 原理：利用fileReader的readAsDataURL，将blob转为base64
 * @param blob
 * @returns {Promise<unknown>}
 */
export const blobToBase64 = (blob) => {
    return new Promise((resolve, reject) => {
        const fileReader = new FileReader()
        fileReader.onload = (e) => {
            resolve(e.target.result)
        }
        // readAsDataURL
        fileReader.readAsDataURL(blob)
        fileReader.onerror = () => {
            reject(new Error('文件流异常'))
        }
    })
}

/**
 * url转blob
 * @param url
 * @returns {Promise<minimist.Opts.unknown>}
 */
export const urlToBlob = (url) => {
    return base64ToBlob(urlToBase64(url))
}

/**
 * 复制文本到粘贴板
 * @param text
 */
export const copyText = (text) => {
    // js创建一个input输入框
    const input = document.createElement('input')
    // 将需要复制的文本赋值到创建的input输入框中
    input.value = text.toString()
    // 将输入框暂时创建到实例里面
    document.body.appendChild(input)
    // 选中输入框中的内容
    input.select()
    // 执行复制操作
    if (document.execCommand('Copy')) {
        // console.log(`copy success! val: ${text}`)
       Message({
          type: 'success',
          message: Vue.prototype.$lang.Copy_Success
        })
      } else {
        // console.log('copy failure!')
      }
    // 最后删除实例中临时创建的input输入框，完成复制操作
    document.body.removeChild(input)
}

/**
 * 获取当前月份的第一天
 * @returns {string}
 */
export const getCurrentMonthFirst = () => {
    const now = new Date()
    const nowMonth = now.getMonth()
    const nowYear = now.getFullYear()
    // 本月的开始时间
    return new Date(nowYear, nowMonth, 1)
}

/**
 * 获取当前月份的最后一天
 * @returns {string}
 */
export const getCurrentMonthLast = () => {
    const now = new Date()
    const nowMonth = now.getMonth()
    const nowYear = now.getFullYear()
    // 本月的结束时间
    return new Date(nowYear, nowMonth + 1, 0)
}


/**
 * 获取近今日的日期时间
 * @returns {number[]}
 */
export const getAroundTodayRangeTime = () => {
    const now = new Date()
    const nowDate = now.getDate();
    const nowMonth = now.getMonth()
    const nowYear = now.getFullYear()
    const start = new Date(nowYear, nowMonth, nowDate)
    const end = new Date(nowYear, nowMonth, nowDate, 23, 59, 59)
    const rangeTime = [start.getTime(), end.getTime()]
    // console.log('rangeTime', rangeTime)
    return rangeTime
}


/**
 * 获取近昨日的日期时间
 * @returns {number[]}
 */
export const getAroundYesterdayRangeTime = () => {
    const now = new Date()
    const nowDate = now.getDate();
    const nowMonth = now.getMonth()
    const nowYear = now.getFullYear()
    const start = new Date(nowYear, nowMonth, nowDate - 1)
    const end = new Date(start.getFullYear(), start.getMonth(), start.getDate(), 23, 59, 59)
    const rangeTime = [start.getTime(), end.getTime()]
    // console.log('rangeTime', rangeTime)
    return rangeTime
}


/**
 * 获取近七天的日期时间
 * @returns {number[]}
 */
export const getAround7DayRangeTime = () => {
    const now = new Date()
    const nowDate = now.getDate();
    const nowMonth = now.getMonth()
    const nowYear = now.getFullYear()
    const start = new Date(nowYear, nowMonth, nowDate - 6)
    const end = new Date(nowYear, nowMonth, nowDate, 23, 59, 59)
    const rangeTime = [start.getTime(), end.getTime()]
    // console.log('rangeTime', rangeTime)
    return rangeTime
}

/**
 * 获取近30天的日期时间
 * @returns {number[]}
 */
export const getAround30DayRangeTime = () => {
    const now = new Date()
    const nowDate = now.getDate();
    const nowMonth = now.getMonth()
    const nowYear = now.getFullYear()
    const start = new Date(nowYear, nowMonth, nowDate - 29)
    const end = new Date(nowYear, nowMonth, nowDate, 23, 59, 59)
    const rangeTime = [start.getTime(), end.getTime()]
    // console.log('rangeTime', rangeTime)
    return rangeTime
}

/**
 * 获取近90天的日期时间
 * @returns {number[]}
 */
export const getAround90DayRangeTime = () => {
    const now = new Date()
    const nowDate = now.getDate();
    const nowMonth = now.getMonth()
    const nowYear = now.getFullYear()
    const start = new Date(nowYear, nowMonth, nowDate - 89)
    const end = new Date(nowYear, nowMonth, nowDate, 23, 59, 59)
    const rangeTime = [start.getTime(), end.getTime()]
    // console.log('rangeTime', rangeTime)
    return rangeTime
}


/**
 * 获取一个月的日期时间
 * @returns {number[]}
 */
export const getAroundOneMonthRangeTime = () => {
    const now = new Date()
    const nowMonth = now.getMonth()
    const nowYear = now.getFullYear()
    const start = new Date(nowYear, nowMonth, 1)
    const end = new Date(nowYear, nowMonth + 1, 0, 23, 59, 59)
    const rangeTime = [start.getTime(), end.getTime()]
    // console.log('rangeTime', rangeTime)
    return rangeTime
}

/**
 * 获取半年日期时间
 * @returns {number[]}
 */
export const getAroundHalfYearRangeTime = () => {
    const end = new Date()
    end.setHours(23)
    end.setMinutes(59)
    end.setSeconds(59)
    const start = new Date()
    start.setMonth(start.getMonth() - 6)
    const rangeTime = [start.getTime(), end.getTime()]
    // console.log('rangeTime', rangeTime)
    return rangeTime
}

/**
 * 获取一年日期时间
 * @returns {number[]}
 */
export const getAroundOneYearRangeTime = () => {
    const end = new Date()
    end.setHours(23)
    end.setMinutes(59)
    end.setSeconds(59)
    const start = new Date()
    start.setMonth(start.getMonth() - 12)
    const rangeTime = [start.getTime(), end.getTime()]
    // console.log('rangeTime', rangeTime)
    return rangeTime
}

/**
 * 获取两个日期相差天数
 * @param date_1
 * @param date_2
 * @returns {number}
 */
export const getDiffDay = (date_1, date_2) => {
    let totalDays, diffDate
    diffDate = Math.abs(date_1 - date_2)
    totalDays = Math.floor(diffDate / (1000 * 3600 * 24))
    return totalDays
}

/**
 * 比较时间1字符串大于或等于时间2字符串
 *
 * 22:00, 10:00 > true
 * 22:00, 22:00 = true
 * 10:00, 22:00 < false
 * @param time1
 * @param time2
 */
export const timeStrGTE = (time1, time2) => {
    if (time1 !== null && time2 !== null) {
        const s1 = time1.split(':')
        const s2 = time2.split(':')
        if (Number(s1[0]) > Number(s2[0])) {
            return true
        } else if (Number(s1[0]) === Number(s2[0])) {
            if (Number(s1[1]) > Number(s2[1])) {
                return true
            } else if ((Number(s1[1]) > Number(s2[1]))) {
                return true
            } else {
                return false
            }
        } else {
            return false
        }
    } else {
        return false
    }
}

/**
 * @description blobToFile
 * @param {Blob} blob
 * @param {String} fileName
 */
export const blobToFile = (blob, fileName) => {
    return new window.File([blob], fileName, {
        type: blob.type
    })
}

//金额格式化
export const amountFormat = (amount) => {
    let val
    if (amount || amount == 0) {
        val = formatAmount(amount)
    } else if (amount == '' || amount == null || amount == undefined) {
        val = '0.00'
    }
    return val
}

export const getUUID = () => {
    const s = [];
    const hexDigits = "0123456789abcdef";
    for (let i = 0; i < 32; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[8] = s[13] = s[18] = s[23];
    const uuid = s.join("");
    return uuid;
}


/**
 * 校验金额
 * @param val
 * @param min 最小值
 * @param max 最大值
 */
export const checkAmount = (val, min = 1, max = 9999999) => {
    const originalVal = val
    if (!val || isNaN(val)) {
        return min ? min : 1
    }
    // 清除"数字"/"."/以外的字符
    val = val.replace(/[^\d.]/g, '')
    // 开头为小数点清除
    val = val.replace(/^\./g, '')
    // 只保留第一个.清除多余的
    val = val.replace(/\.{2,}/g, '.')
    val = val.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
    // 只能输入三个小数
    val = val.replace(/^(-)*(\d+)\.(\d\d\d).*$/, '$1$2.$3')

    // 边界值处理
    val = parseFloat(val)
    if (min) {
        min = parseFloat(min)
        val = val < min ? min : val
    }
    if (max) {
        max = parseFloat(max)
        val = val > max ? max : val
    }
    // console.log(`checkAmount, before: ${originalVal}  after: ${val}`)
    return val
}

/**
 * 校验数字
 * @param val
 * @param min 最小值
 * @param max 最大值
 */
export const checkNumber = (val, min = 0, max = 9999999) => {
    if (!val || isNaN(val)) {
        return min ? min : 0
    }

    // 边界值处理
    val = parseInt(val)
    if (min) {
        min = parseInt(min)
        val = val < min ? min : val
    }
    if (max) {
        max = parseInt(max)
        val = val > max ? max : val
    }
    // console.log(`checkNumber: ${val}`)
    return val
}


/**
 * list转map
 * @param list
 * @returns {{}}
 */
export const list2mapForConfig = (list) => {
    let map = {}
    if (list && list.length > 0) {
        list.forEach(item => {
            map[item.key] = item.value
        })
    }
    return map
}

/**
 * map转list
 * @param list
 * @returns {{}}
 */
export const map2listForConfig = (map) => {
    let list = []
    Object.keys(map).forEach(key => {
        list.push({key: key, value: map[key]})
    })
    return {
        sysConfigs: list
    }
}

/**
 * 替换路径上的分页参数
 * @param url
 * @param page
 * @returns {*}
 */
export const replacePageNumAndSize = (url, page) => {
    let res = url
    if (url && page && page.current && page.size) {
        res = res.replace('{pageNum}', page.current)
        res = res.replace('{pageSize}', page.size)
    }
    // console.log(url, page, res)
    return res
}

/**
 * 构建卡过期str
 * @param month
 * @param year
 * @returns {*}
 */
export const buildCardExpire = (month, year) => {
    let res = ''
    if (month && year) {
        let tempMonth = parseInt(month)
        res = tempMonth < 10 ? `0${tempMonth}/${month}` : `${tempMonth}/${month}`
    }
    return res
}


/**
 * 构建图表XY轴数据
 * @param data
 * @returns {{xData: *[], yData: *[]}}
 */
export const buildChartXYDataForTimestamp = (data, unit,isAmount = false,type = true) => {
    const xData = []
    const yData = []
    const items = []
    if (data && data.data && data.data.length > 0) {
        data.data.forEach(item => {
            let dateTime = moment(item.timestamp).format(type ? 'YYYY-MM-DD   HH:mm' : 'HH:mm')
            let time = moment(item.timestamp).format(unit == 'hour' ? 'HH:mm' : 'MM-DD')
            let amountText = ''
            if (isAmount) {
                amountText += data.currency ? `${data.currency} ` : ''
                amountText += amountFormat(item.value)
            }
            xData.push(time)
            yData.push(item.value)
            // console.log(item);
            items.push({
                timestamp: item.timestamp,
                value: item.value,
                dateTime: dateTime,
                time: time,
                isAmount: isAmount,
                amountText: amountText,
            })
        })
    }
    return {items:items, xData: xData, yData: yData}
}

/**
 * 构建权限数据
 * @param permissions
 * @returns {{}}
 */
export const buildPermissions = (permissions) => {
    const map = {}
    if (permissions && permissions.length > 0) {
        permissions.forEach(item => {
            map[item] = true
        })
    }

    map['105'] = true

    return map
}

/**
 * 文件路径格式化
 * @param val
 * @param fileHost
 * @returns {string}
 */
export const fileUrlFormat = (val, fileHost) => {
    let res = ''
    if (val) {
        if (val.startsWith('http://') || val.startsWith('https://')) {
            res = val
        } else {
            res = fileHost ? fileHost + val : val
        }
    }
    return res
}

/**
 * 语言格式化
 * @param val
 * @returns {{}}
 */
export const langFormat = (val) => {
    let lang = cache.getLang()
    if (!lang) {
        lang = 'VI'
    }
    // console.log('langFormat', lang, val)
    let res = ''
    if (val === null || val === '') {
        return res
    }
    
    // 如果val是字符串，直接返回
    if (typeof val === 'string') {
        return val
    }
    
    // 如果val是对象，尝试获取对应语言的翻译，如果为空则使用回退语言
    if (typeof val === 'object') {
        switch (lang) {
            case 'VI':
                res = val.vi || val.zh || val.en || val
                break
            case 'CN':
                res = val.zh || val.en || val.vi || val
                break
            case 'EN':
                res = val.en || val.zh || val.vi || val
                break
        }
    } else {
        res = val
    }
    
    return res
}

export const EventBus = new Vue();
